package net.simpleframework.swing;

import java.io.StringReader;
import java.util.Date;

import javax.swing.SwingConstants;
import javax.swing.table.TableColumn;

import net.simpleframework.core.ado.db.Column;
import net.simpleframework.util.IoUtils;
import net.simpleframework.util.StringUtils;

import org.jdesktop.swingx.table.DefaultTableColumnModelExt;
import org.jdesktop.swingx.table.TableColumnExt;

/**
 * 这是一个开源的软件，请在LGPLv3下合法使用、修改或重新发布。
 * 
 * @author 陈侃(cknet@126.com, 13910090885)
 *         http://code.google.com/p/simpleframework/
 *         http://www.simpleframework.net
 */
public class JTableExColumn extends Column {
	private static final long serialVersionUID = -3521977571466252887L;

	private String format;

	private FilterExpression lastFilterExpression, filterExpression;

	private boolean sort;

	private int columnWidth;

	private int alignment = -1;

	private int originalIndex;

	private int modelIndex = -1;

	private boolean freezable = false;

	private String tooltip;

	JAbstractTableEx table;

	public JTableExColumn(final String columnName) {
		super(columnName);
	}

	public JTableExColumn(final String columnName, final String columnText) {
		super(columnName, columnText);
	}

	public int getOriginalIndex() {
		return originalIndex;
	}

	public void setOriginalIndex(final int originalIndex) {
		this.originalIndex = originalIndex;
	}

	public int getModelIndex() {
		if (modelIndex == -1) {
			final TableColumn tc = getTableColumn();
			if (tc != null) {
				modelIndex = tc.getModelIndex();
			}
		}
		return modelIndex;
	}

	public void setModelIndex(final int modelIndex) {
		this.modelIndex = modelIndex;
	}

	public TableColumnExt getTableColumn() {
		return table == null ? null : ((DefaultTableColumnModelExt) table.getColumnModel())
				.getColumnExt(this);
	}

	@Override
	public void setVisible(final boolean visible) {
		super.setVisible(visible);
		final TableColumnExt tc = getTableColumn();
		if (tc != null) {
			tc.setVisible(visible);
		}
	}

	@Override
	public String getColumnText() {
		final String columnText = super.getColumnText();
		try {
			final String[] texts = IoUtils.getStringsFromReader(new StringReader(columnText));
			if (texts.length > 1) {
				return "<html>" + StringUtils.join(texts, "<br/>") + "</html>";
			}
		} catch (final Exception e) {
		}
		return columnText;
	}

	@Override
	public void setColumnText(final String columnText) {
		super.setColumnText(columnText);
		final TableColumnExt tc = getTableColumn();
		if (tc != null) {
			tc.setHeaderValue(columnText);
		}
	}

	public int getAlignment() {
		if (alignment == -1) {
			final Class<?> c = getBeanPropertyType();
			if (c != null) {
				if (Date.class.isAssignableFrom(c)) {
					return SwingConstants.CENTER;
				} else if (Number.class.isAssignableFrom(c)) {
					return SwingConstants.RIGHT;
				}
			}
			return SwingConstants.LEFT;
		} else {
			return alignment;
		}
	}

	public int getColumnWidth() {
		return columnWidth;
	}

	public void setColumnWidth(final int columnWidth) {
		this.columnWidth = columnWidth;
	}

	public void setAlignment(final int alignment) {
		this.alignment = alignment;
	}

	public String getFormat() {
		return format;
	}

	public void setFormat(final String format) {
		this.format = format;
	}

	public boolean isFreezable() {
		return freezable;
	}

	public void setFreezable(final boolean freezable) {
		this.freezable = freezable;
	}

	public FilterExpression getFilterExpression() {
		return filterExpression;
	}

	public FilterExpression getLastFilterExpression() {
		return lastFilterExpression;
	}

	public void setFilterExpression(final FilterExpression filterExpression) {
		this.filterExpression = filterExpression;
		if (filterExpression != null) {
			lastFilterExpression = filterExpression;
		}
	}

	public String getTooltip() {
		return tooltip;
	}

	public void setTooltip(final String tooltip) {
		this.tooltip = tooltip;
	}

	public boolean isSort() {
		return sort;
	}

	public void setSort(final boolean sort) {
		this.sort = sort;
	}

	FilterExpression createFilterExpression() {
		return new FilterExpression();
	}

	FilterItem createFilterItem() {
		return new FilterItem();
	}

	final static String SPACE = " ";

	class FilterExpression {
		public FilterItem item1;

		public String ope;

		public FilterItem item2;

		@Override
		public String toString() {
			String s = "";
			if (item1 != null) {
				s += item1.toString();
			}
			if (item2 != null) {
				s += SPACE + StringUtils.text(ope, "and") + SPACE + item2.toString();
			}
			return s;
		}

		public String getTooltip() {
			String s = "";
			if (item1 != null) {
				s += item1.getTooltip();
			}
			if (item2 != null) {
				s += SPACE + StringUtils.text(ope, "and") + SPACE + item2.getTooltip();
			}
			return s;
		}
	}

	class FilterItem {
		public String relation;

		public Object value;

		public Object toValue() {
			if ("like".equalsIgnoreCase(relation)) {
				return "%" + value + "%";
			} else {
				return value;
			}
		}

		@Override
		public String toString() {
			final StringBuilder sb = new StringBuilder();
			sb.append(getColumnSqlName()).append(" ").append(relation).append(" ?");
			return sb.toString();
		}

		String getTooltip() {
			final StringBuilder sb = new StringBuilder();
			sb.append(getColumnText()).append(" ").append(relation).append(" ")
					.append(table.convertToString(JTableExColumn.this, toValue()));
			return sb.toString();
		}
	}
}
